Passed
Branchmaster (c9c96e)
by Plamen
01:28
created

table.js ➔ ... ➔ this.DrawSection   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 18
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 5
Bugs 1 Features 1
Metric Value
cc 4
eloc 13
c 5
b 1
f 1
nc 3
nop 3
dl 0
loc 18
rs 9.75
1
var strAsc = String.fromCharCode(9650); //▲
2
var strDesc = String.fromCharCode(9660);//▼
3
var xmlhttp;
4
var d;
5
6
var table = new function () {
7
    this.rq = null;
8
    this.tail = [];
9
10
    this.ReloadData = function (tableId) {
11
        var request = {};
12
        this.BuildRequest(request, tableId);
13
        this.LoadData(tableId, request);
14
    };
15
16
    this.BuildRequest = function (request, crntTableId, skipPropertyArray) {
17
        this.rq = request;
18
        this.checkSkip = function (skipProperty) {
19
            var result = false;
20
            if (skipPropertyArray && Object.prototype
21
                    .toString.call(skipPropertyArray) === '[object Array]') {
22
                if (skipPropertyArray.indexOf(skipProperty) >= 0) {
23
                    result = true;
24
                }
25
            }
26
            return result;
27
        };
28
        this.getSort = function () {
29
            var table = document.getElementById(crntTableId);
30
            var thTags = table.getElementsByTagName("thead")[0]
31
                    .getElementsByTagName("th");
32
            for (var i = 0; i < thTags.length; i++) {
33
                if (thTags[i].getElementsByTagName("a")[0] && thTags[i]
34
                        .getElementsByTagName("a")[0].getElementsByTagName("span")
35
                        .length === 1
36
                        ) {
37
                    var order = thTags[i].getElementsByTagName("a")[0]
38
                            .getElementsByTagName("span")[0].innerHTML;
39
                    if (order.length === 1) {
40
                        this.rq.colNo = i;
41
                        this.rq.colOrd = (order === window.strDesc) ?
42
                                "desc" : "asc";
43
                    }
44
                }
45
            }
46
        };
47
        this.getFilter = function () {
48
            var r = this.getFilterFieldsByTbaleID(crntTableId);
49
            if (r.filter !== null) {
50
                this.rq.filter = r.filter;
51
            }
52
            if (r.filterBy !== null) {
53
                this.rq.filterBy = r.filterBy;
54
            }
55
        };
56
57
        /* Build request object */
58
        if (!this.checkSkip("sort")) {
59
            this.getSort();
60
        }
61
        if (!this.checkSkip("filter")) {
62
            this.getFilter();
63
        }
64
65
        this.rq.tableId = crntTableId;
66
        return this.rq;
67
    };
68
69
    this.RequestToUrl = function (rq) {
70
        var url = location.pathname + ".json" + location.search;
71
        if (typeof rq === "object") {
72
            var getUrlVarName = {
73
                colNo: "col", colOrd: "ord", filter: "filter",
74
                filterBy: "filter-by", pageNo: "pg", exportType: "export",
75
                tableId: "table-id"
76
            };
77
            var flagFirst = location.search.length < 1 ? true : false;
78
            for (var r in rq) {
79
                if (!rq.hasOwnProperty(r)) {
80
                    continue; // Skip keys from the prototype.
81
                }
82
                var clue = flagFirst === true ? "?" : "&";
83
                url += clue + getUrlVarName[r] + "=" + rq[r];
84
                flagFirst = false;
85
            }
86
        }
87
        return url;
88
    };
89
90
    this.Filter = function (field) {
91
        var crntTableId = this.FilterGetTableId(field);
92
        if (crntTableId !== null) {
93
            var request = {};
94
            var exRq = this.rq;
95
            this.BuildRequest(request, crntTableId);
96
            if (exRq === null ||
97
                request.filter !== exRq.filter ||
98
                request.filterBy !== exRq.filterBy
99
            ) {
100
                this.LoadData(crntTableId, request);
101
            }
102
        }
103
    };
104
105
    this.FilterGetTableId = function (field) {
106
        if (field.tagName.toLowerCase() !== "select") {
107
            return field.getAttribute("data-table-id");
108
        } else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
109
            var f = field.parentNode.parentNode.getElementsByTagName("input")[0];
110
            return '' === f.value ? null : f.getAttribute("data-table-id");
111
        }
112
    };
113
114
    this.GoPage = function (lnk) {
115
        var request = {};
116
        var table = this.getParent(lnk, "table");
117
        var crntTableId = table.getAttribute("id");
118
        this.BuildRequest(request, crntTableId);
119
        //check & serve pagination jump links
120
        var jumpDir = lnk.innerHTML.trim().substr(0, 1);
121
        if (jumpDir === "+" || jumpDir === "-") {
122
            var current = table.querySelector("tfoot .paging .a").innerHTML;
123
            var jump = lnk.innerHTML.replace("K", "000").replace("M", "000000000");
124
            var jumpPage = (parseInt(current) + parseInt(jump));
125
            lnk.parentNode.setAttribute("data-page", jumpPage);
126
            lnk.style.transform = "none";
127
        }
128
        request.pageNo = lnk.parentNode.hasAttribute("data-page") ?
129
                lnk.parentNode.getAttribute("data-page") :
130
                lnk.innerHTML;
131
        this.LoadData(crntTableId, request);
132
        return false;
133
    };
134
135
    this.Export = function (lnk, eType) {
136
        var request = {};
137
        var crntTableId = this.getParent(lnk, "table").getAttribute("id");
138
        this.BuildRequest(request, crntTableId);
139
        request.exportType = ["CSV", "Excel"].indexOf(eType) >= 0 ? eType : "csv";
140
        window.open(this.RequestToUrl(request));
141
        return false;
142
    };
143
144
    this.Sort = function (colNo, lnk) {
145
        var request = {};
146
        var crntTableId = this.getParent(lnk, "table").getAttribute("id");
147
        this.BuildRequest(request, crntTableId);
148
        if (Math.round(colNo) === request.colNo) {
149
            request.colOrd = request.colOrd === "asc" ? "desc" : "asc";
150
        } else {
151
            request.colNo = Math.round(colNo);
152
            request.colOrd = "asc";
153
        }
154
        this.LoadData(crntTableId, request);
155
        /* Clear and add new sort arrow */
156
        var headSpans = this.getParent(lnk, "thead").getElementsByTagName("span");
157
        var length = headSpans.length;
158
        for (var i = 0; i < length; i++) {
159
            headSpans[i].innerHTML = "";
160
        }
161
        lnk.getElementsByTagName("span")[0].innerHTML = (request.colOrd === "desc" ? window.strDesc : window.strAsc);
162
    };
163
164
    this.DrawSection = function (tableContainer, dt, tSection) {
165
        var section = tSection === "tfoot" ? "tfoot" : "tbody";
166
        tSection = document.getElementById(tableContainer).
167
                getElementsByTagName(section)[0];
168
        this.clearSection(tSection);
169
        for (var i = 0; i < dt.length; i++) {
170
            var row = dt[i];
171
            var tRow = document.createElement("tr");
172
173
            this.DrawRow(row, tRow);
174
175
            tSection.appendChild(tRow);
176
            if (section === "tfoot") {
177
                this.footerProcessPaginationLinks(tSection);
178
            }
179
            this.AppendRowCalback(tableContainer);
180
        }
181
    };
182
183
    this.DrawRow = function(row, tRow){
184
        for(var cell in row){
185
            if ( ! row.hasOwnProperty(cell)) {
186
                continue; // Skip keys from the prototype.
187
            }
188
            var tCell = document.createElement("td");
189
            if(typeof row[cell] === "string" || typeof row[cell] === "number"){
190
                tCell.innerHTML = row[cell];
191
            } else if(typeof row[cell] === "object"){
192
                this.DrawCellFromObject(row, cell, tCell);
193
            }
194
            tRow.appendChild(tCell);
195
        }
196
    };
197
198
    this.DrawCellFromObject = function (row, cell, tCell) {
199
        for (var attr in row[cell]) {
1 ignored issue
show
Complexity introduced by
A for in loop automatically includes the property of any prototype object, consider checking the key using hasOwnProperty.

When iterating over the keys of an object, this includes not only the keys of the object, but also keys contained in the prototype of that object. It is generally a best practice to check for these keys specifically:

var someObject;
for (var key in someObject) {
    if ( ! someObject.hasOwnProperty(key)) {
        continue; // Skip keys from the prototype.
    }

    doSomethingWith(key);
}
Loading history...
200
            if (typeof row[cell][attr] === "string") {
201
                tCell.innerHTML = row[cell][attr];
202
            } else if (typeof row[cell][attr] === "object") {
203
                for (var v in row[cell][attr]) {
1 ignored issue
show
Complexity introduced by
A for in loop automatically includes the property of any prototype object, consider checking the key using hasOwnProperty.

When iterating over the keys of an object, this includes not only the keys of the object, but also keys contained in the prototype of that object. It is generally a best practice to check for these keys specifically:

var someObject;
for (var key in someObject) {
    if ( ! someObject.hasOwnProperty(key)) {
        continue; // Skip keys from the prototype.
    }

    doSomethingWith(key);
}
Loading history...
204
                    tCell.setAttribute(v, row[cell][attr][v]);
205
                }
206
            }
207
        }
208
    };
209
210
    this.footerProcessPaginationLinks = function (tSection) {
211
        var pLinks = tSection.querySelectorAll(".paging a");
212
        if (pLinks.length > 0) {
213
            for (var j = 0; j < pLinks.length; j++) {
214
                pLinks[j].setAttribute("href", "javascript:void(0);");
215
                pLinks[j].setAttribute("onclick", "return table.GoPage(this);");
216
            }
217
        }
218
    };
219
220
    this.clearSection = function (tSection) {
221
        if (this.iePrior(9)) {
222
            if (tSection.firstChild) {
223
                while (tSection.firstChild) {
224
                    tSection.removeChild(tSection.firstChild);
225
                }
226
            }
227
        } else {
228
            tSection.innerHTML = "";
229
        }
230
    };
231
232
    this.SetTheTableColumnsHoverEffect = function (tableContainer) {
233
        if (this.iePrior(9)) {
234
            return;
235
        }
236
        var tContainer = document.getElementById(tableContainer);
237
        var tHcells = tContainer.rows[0].cells;
238
        for (var i = 0; i < tHcells.length; i++) {
239
            if (tHcells[i].firstChild.tagName === "A") {
240
                tHcells[i].firstChild.setAttribute("onmouseover", "table.ColumnHover('" + tableContainer + "'," + i + ");");
241
                tHcells[i].firstChild.setAttribute("onmouseout", "table.ColumnHover('" + tableContainer + "');");
242
            }
243
        }
244
        var pLinks = tContainer.querySelectorAll("tfoot .paging a");
245
        if (pLinks.length > 0) {
246
            for (var j = 0; j < pLinks.length; j++) {
247
                pLinks[j].setAttribute("href", "javascript:void(0);");
248
                pLinks[j].setAttribute("onclick", "return table.GoPage(this);");
249
            }
250
        }
251
    };
252
253
    this.ColumnHover = function (tableContainer, index) {
254
        if (this.iePrior(9)) {
255
            return;
256
        }
257
        var tRow = document.getElementById(tableContainer).rows;
258
        index = Math.round(index);
259
        for (var i = 0; i < (tRow.length - 1); i++) {
260
            if (index >= 0) {
261
                tRow[i].cells[index].setAttribute("lang", "col-hover");
262
            } else {
263
                for (var j = 0; j < tRow[i].cells.length; j++) {
264
                    if (tRow[i].cells[j].lang) {
265
                        tRow[i].cells[j].removeAttribute("lang");
266
                    }
267
                }
268
            }
269
        }
270
    };
271
272
    this.getFilterFieldsByTbaleID = function (tableID) {
273
        var fields = {filterBy: null, filter: null};
274
        var filterDiv = this.getFilterDivByTableIDOrNull(tableID);
275
        if (filterDiv !== null) {
276
            var selectObj = filterDiv.getElementsByTagName("select")[0];
277
            var textObj = filterDiv.getElementsByTagName("input")[0];
278
            fields.filterBy = (selectObj === null || selectObj.options[selectObj.selectedIndex].value === "all") ? null : selectObj.options[selectObj.selectedIndex].value;
279
            fields.filter = (textObj === null || textObj.value.length === 0) ? null : encodeURIComponent(textObj.value.trim());
280
        }
281
        return fields;
282
    };
283
284
    this.getFilterDivByTableIDOrNull = function (tableID) {
285
        var res = null;
286
        if (document.getElementById(tableID).parentNode.getElementsByTagName("div").length > 0) {
287
            for (var i = 0; i < document.getElementById(tableID).parentNode.getElementsByTagName("div").length; i++) {
288
                if (document.getElementById(tableID).parentNode.getElementsByTagName("div")[i].getAttribute("class") === "filter") {
289
                    return document.getElementById(tableID).parentNode.getElementsByTagName("div")[i];
290
                }
291
            }
292
293
        }
294
        return res;
295
    };
296
297
    this.LoadData = function (tableContainer, rq) {
298
        this.setVisability(tableContainer, false);
299
        if (window.XMLHttpRequest) {
300
            xmlhttp = new XMLHttpRequest();/* code for IE7+, Firefox, Chrome, Opera, Safari */
301
        } else { /** global: ActiveXObject */
302
            xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");/*code for IE6, IE5 */
0 ignored issues
show
Bug introduced by
The variable ActiveXObject seems to be never declared. If this is a global, consider adding a /** global: ActiveXObject */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
303
        }
304
        for (var i = 0; i < this.tail.length; i++) {
305
            var ex_xmlhttp = this.tail.shift();
306
            ex_xmlhttp.abort();
307
        }
308
        xmlhttp.onreadystatechange = function () {
309
            if (xmlhttp.readyState === 4 && xmlhttp.status === 200) {
310
                d = JSON.parse(xmlhttp.responseText);
311
                table.DrawSection(tableContainer, d.body);
312
                table.DrawSection(tableContainer, d.footer, "tfoot");
313
                table.LoadEndCalback(tableContainer);
314
                table.setVisability(tableContainer, true);
315
                if (typeof rq === "object") {
316
                    table.ColumnHover(tableContainer, rq.colNo);
317
                }
318
            }
319
        };
320
        xmlhttp.open("GET", this.RequestToUrl(rq), true);
321
        xmlhttp.send();
322
        this.tail.push(xmlhttp); //put in tail to may later abort any previous
323
    };
324
325
    this.setVisability = function (tableContainer, rq) {
326
        var tbl = document.getElementById(tableContainer);
327
        if (rq === true) {
328
            tbl.style.filter = "none";
329
            tbl.style.opacity = "1";
330
            tbl.style.cursor = "auto";
331
        } else if (rq === false) {
332
            tbl.style.filter = "blur(1px)";
333
            tbl.style.opacity = "0.8";
334
            tbl.style.cursor = "wait";
335
        } else {
336
            console.log("table error in the rq value"); /*Shows error*/
0 ignored issues
show
Debugging Code introduced by
console.log looks like debug code. Are you sure you do not want to remove it?
Loading history...
337
        }
338
    };
339
340
    this.getParent = function (obj, objType) {
341
        while (obj && obj.tagName !== objType.toUpperCase()) {
342
            obj = obj.parentNode;
343
        }
344
        return obj;
345
    };
346
347
    this.init = function (tableId) {
348
        this.SetTheTableColumnsHoverEffect(tableId);
349
    };
350
351
    this.iePrior = function (v) {
352
        var rv = false;
353
        if (/** global: navigator */ navigator.appName === 'Microsoft Internet Explorer') {
0 ignored issues
show
Bug introduced by
The variable navigator seems to be never declared. If this is a global, consider adding a /** global: navigator */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
354
            var ua = navigator.userAgent;
355
            var re = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})");
356
            if (re.exec(ua) !== null) {
357
                rv = parseFloat(RegExp.$1);
358
            }
359
            rv = rv < v ? true : false;
360
        }
361
        return rv;
362
    };
363
    this.loadJS = function (src) {
364
        var s = document.createElement('script');
365
        s.src = src;
366
        document.getElementsByTagName('head')[0].appendChild(s);
367
    };
368
    this.loadCSS = function (src) {
369
        var s = document.createElement('link');
370
        s.href = src;
371
        s.rel = "stylesheet";
372
        document.getElementsByTagName('head')[0].appendChild(s);
373
    };
374
375
    this.LoadEndCalback = function (tableId) {
376
        if (tableId) {/*Allows override*/
0 ignored issues
show
Comprehensibility Documentation Best Practice introduced by
This code block is empty. Consider removing it or adding a comment to explain.
Loading history...
377
        }
378
    };
379
    this.AppendRowCalback = function (tableId) {
380
        if (tableId) {/*Allows override*/
0 ignored issues
show
Comprehensibility Documentation Best Practice introduced by
This code block is empty. Consider removing it or adding a comment to explain.
Loading history...
381
        }
382
    };
383
};
384
385
/** Moves custom created filter to the Table's filter
386
 * @param {string} filterId
387
 * @param {string} tableId
388
 * @param {boolean} delay - needed in case the table is istill not executed */
389
function moveSelectorToTheTableFilter(filterId, tableId, delay) {
390
    if (delay === true) {
391
        setTimeout(function () {
392
            var filterDiv = document.getElementById(tableId)
393
                    .getElementsByTagName("div")[0];
394
            filterDiv.appendChild(document.getElementById(filterId));
395
        }, 500);
396
    } else {
397
        var filterDiv = document.getElementById(tableId)
398
                .getElementsByTagName("div")[0];
399
        filterDiv.appendChild(document.getElementById(filterId));
400
    }
401
}
402
function changeListCustomFilter(selectObj) {
403
    var fId = selectObj.options[selectObj.selectedIndex].value;
404
    var hasValue = fId !== "{!--Empty--!}";
405
    var varName = selectObj.getAttribute("name");
406
    var varPos = (document.URL.indexOf(varName) - (hasValue ? 0 : 1));
407
    if (varPos > 0) {
408
        var url = document.URL.substring(0, varPos);
409
    } else {
410
        var separator = document.URL.indexOf("?") > 0 ? "&" : "?";
411
        url = document.URL + (hasValue ? separator : "");
412
    }
413
    var newUrl = url + (hasValue ? (varName + "=" + fId) : "");
414
    location.assign(newUrl);
415
}
416
417
418
function tablesLoadData() {
419
    var tables = document.getElementsByTagName("table");
420
    var envPrior9 = table.iePrior(9);
421
    for (var i = 0; i < tables.length; i++) {
422
        var isProcessable = envPrior9 ?
423
                typeof tables[i]["data-table"] !== 'undefined' :
424
                tables[i].hasAttribute("data-table");
425
        if (isProcessable && tables[i].getAttribute("data-table") === "js") {
426
            table.LoadData(tables[i].id);
427
            table.SetTheTableColumnsHoverEffect(tables[i].id);
428
        }
429
    }
430
    if (table.iePrior(10)) {
431
        table.loadJS("/add/helpers/table/add/json2.js");
432
    }
433
434
    /*if(table.iePrior(8)){ //can be used to add apropriate tables links modifications
435
     // loadCSS("/add/helpers/table/add/ie7-and-down.css");
436
     }*/
437
}
438
439
/*if(window.addEventListener){window.addEventListener('load',tablesLoadData,false);} else if(window.attachEvent){window.attachEvent('onload',tablesLoadData);}*/